<?php

declare(strict_types=1);

namespace App\Service\Rbac;

use App\Dao\{AuthRoleDao, AuthRolePermissionDao,AuthAdminLogDao,AuthEmployeeDao};
use App\Constants\{DefaultValue,ErrorCode};
use App\Exception\BusinessException;
use Hyperf\Di\Annotation\Inject;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\Context;
use App\Dao\AuthAdminLogDao as RoleAdminDao;

class AuthRoleService
{
    /**
     * @Inject
     * @var AuthRoleDao
     */
    protected $roleDao;

    /**
     * @Inject
     * @var AuthRolePermissionDao
     */
    protected $rolePermissionDao;

    protected $token;

    public function __construct()
    {
        $this->token = Context::get('jwt_token');
    }

    // 可以查看默认角色 自己公司和下属创建的角色
    public function listRole(int $page, int $pageSize) : array
    {
        $where = [];
        $data = $this->roleDao->searchByWherePage($pageSize,$page,$where);
        foreach ($data['data'] as &$item) {
            $item['permission_id'] = $this->roleDao->rolePermissionByRoleID($item['id']);
        }
        return $data;
    }

    public function addRole(array $data)
    {
        $info  = $this->roleDao->firstByWhereTrait(['name'=>$data['name']]);
        if ($info) throw new BusinessException(ErrorCode::ERR_BUESSUS, '角色名已被占用');
        try {
            Db::beginTransaction();
            $permission_ids = explode(',',$data['permission_id']);
            unset($data['permission_id']);
            $data['add_time'] = time(); $data['admin_id'] = $this->token['uid'];
            $data['admin_name'] = $this->token['account'];
            $obj = $this->roleDao->insertGetIdTrait($data);
            if ($obj) {
                // 新增角色权限
                $map = [];
                foreach ($permission_ids as $k => $v) {
                    $temp = ['permission_id' => $v, 'role_id'=>$obj];
                    $map[] = $temp;
                }
                $this->rolePermissionDao->insertTrait($map);
                make(AuthAdminLogDao::class)->addLog('新增了角色权限'.json_encode(['role'=>$obj,'permission'=>$permission_ids]));
                Db::commit();
                return $obj;
            }
        } catch (\Throwable $t) {
            Db::rollBack();
            throw new BusinessException(ErrorCode::ERR_BUESSUS, '网络繁忙,请重试@#新增角色+权限失败');
        }
    }

    public function editRoleGet(int $id) : array
    {
        $obj = $this->roleDao->findTrait($id);
        if ($obj) {
            $permissions = $this->roleDao->rolePermissionByRoleID($obj->id);
            return ['role'=>$obj->toArray(), 'permission_id'=>$permissions];
        }
        throw new BusinessException(ErrorCode::ERR_BUESSUS, '角色不存在');
    }

    public function editRolePost(array $data)
    {
        $data['id'] = (int)$data['id'];
        $obj = $this->roleDao->findTrait($data['id']);
        if (!$obj) throw new BusinessException(ErrorCode::ERR_BUESSUS, '角色不存在');
        $ori = json_encode($obj->toArray());
        $info = $this->roleDao->firstByWhereTrait(['name'=>$data['name']]);
        if ($info && $info->id != $data['id']) throw new BusinessException(ErrorCode::ERR_BUESSUS, '角色名已被占用');
        Db::beginTransaction();
        try {
            $role_data = [
                'update_time' => time(),
                'name' => $data['name'],
                'admin_id' => $this->token['uid'],
                'admin_name' => $this->token['account'],
            ];
            $role_edit = $this->roleDao->updateByWhereTrait(['id' => $data['id']], $role_data);
            if ($role_edit) {
                $old_permission = $this->roleDao->rolePermissionByRoleID($data['id']);
                sort($old_permission,SORT_NUMERIC);
                $old_permission = implode(',', $old_permission);
                $current_permmission = explode(',', $data['permission_id']);
                sort($current_permmission, SORT_NUMERIC);
                $current_permmission = implode(',', $current_permmission);
                $this->rolePermissionDao->deleteRolePermissionByIds([$data['id']]);
                if (! empty($data['permission_id'])){
                    $permisssion_ids = explode(',',$data['permission_id']);
                    $map = [];
                    foreach ($permisssion_ids as $k => $v) {
                        $temp = [];
                        $temp['permission_id'] = $v;
                        $temp['role_id'] = $data['id'];
                        $map[] = $temp;
                    }
                    $this->rolePermissionDao->insertTrait($map);
                }
                make(AuthAdminLogDao::class)->addLog('编辑了角色,信息由原始数据' .$ori. '修改成了' .json_encode($data));
            }
            Db::commit();
            return $data['id'];
        } catch (\Throwable $t){
            Db::rollBack();
            throw new BusinessException(ErrorCode::ERR_BUESSUS, '网络繁忙,请重试@#编辑用户+权限失败');
        }
    }

    public function delRole(int $id)
    {
        $obj = $this->roleDao->findTrait($id);
        if (! $obj) throw new BusinessException(ErrorCode::ERR_BUESSUS, '没有该角色');
        if (!in_array($this->token['uid'],config('web.super'))){
            throw new BusinessException(ErrorCode::ERR_BUESSUS, '非管理员不可用编辑默认角色权限');
        }
        $has_user = make(AuthEmployeeDao::class)->existsByWhereTrait(['role_id'=>$id]);
        if ($has_user) throw new BusinessException(ErrorCode::ERR_BUESSUS, '该角色绑定了用户');
        Db::beginTransaction();
        try {
            $this->rolePermissionDao->deleteRolePermissionByIds([$id]);
            $this->roleDao->delRoleByIds([$id]);
            $arr = $obj->toArray();
            make(AuthAdminLogDao::class)->addLog('删除了角色,内容是'.json_encode($arr));
            Db::commit();
            return $obj->id;
        }catch (\Throwable $t){
            Db::rollBack();
            throw new BusinessException(ErrorCode::ERR_BUESSUS, '网络繁忙,请重试@#删除用户+权限失败');
        }
    }

    public function allRole(int $user_id) : array
    {
        $where = array();
        if (! in_array($user_id , config('web.super'))){
            $where[] = ['admin_id','=',$user_id];
        }
        $data = $this->roleDao->getByWhereTrait($where);
        $data = $data->toArray();
        foreach ($data as &$item) {
            $item['permission_id'] = $this->roleDao->rolePermissionByRoleID($item['id']);
        }
        return $data;
    }
}